﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using Ahmad.A.Ousman.WindowsProxy.Common;

namespace Ahmad.A.Ousman.WindowsProxy.Service
{
    partial class WindowsProxyService : ServiceBase
    {
        #region Properties
        private static String StartUpPath
        {
            get { return Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); }
        }
        private static string DataSourceFileName
        {
            get
            {
                var value = ConfigurationManager.AppSettings["DataSourceFileName"];
                if (String.IsNullOrEmpty(value))
                {
                    value = new StringBuilder(StartUpPath).Append(@"\datasource.xml").ToString();
                    var configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                    configuration.AppSettings.Settings.Add("DataSourceFileName", value);
                    configuration.Save(ConfigurationSaveMode.Modified, true);
                    // Force a reload of a changed section.
                    ConfigurationManager.RefreshSection("appSettings");
                }
                return value;
            }
        }
        private ProxyCollection DataSource { get; set; }
        private Proxy LastSetProxy { get; set; }
        #endregion

        #region Constructor
        public WindowsProxyService()
        {
            InitializeComponent();
        }
        #endregion

        #region Event Handlers
        protected override void OnStart(string[] args)
        {
            SetProxy(true);
        }

        protected override void OnStop()
        {
            Common.Service.SetProxy(null);
        }

        private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            SetProxy(false);
        }
        #endregion

        #region Methods
        private void SetProxy(bool serviceStarted)
        {
            try
            {
                DataSource = new ProxyCollection(DataSourceFileName);
                //Utility.Log(this.ServiceName, String.Format("DataSource Count: {0}", DataSource.Count), EventLogEntryType.Information);
                var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                var datasource = (from ManagementBaseObject networkAdapter in mc.GetInstances() select networkAdapter.Properties["DNSDomain"].Value into dnsDomain where dnsDomain != null select dnsDomain.ToString()).ToList();
                var proxy = DataSource.Find(match => datasource.Contains(match.DnsDomain)) ?? new Proxy();
                if (serviceStarted || !LastSetProxy.Equals(proxy))
                {
                    LastSetProxy = proxy;
                    Common.Service.SetProxy(proxy);
                    Utility.Log(ServiceName, proxy.IsNull ? "Setting Proxy to Null" : String.Format("Setting Proxy: {0} : {1}", proxy.DnsDomain, proxy.ProxyServer), EventLogEntryType.Information);
                }
            }
            catch (Exception exception)
            {
                exception.Log(ServiceName);
            }
        }
        #endregion
    }
}